package cn.cxyxj.study02;

import cn.cxyxj.study02.config.MyAuthenticationEntryPoint;
import cn.cxyxj.study02.config.MyAuthenticationFailureHandler;
import cn.cxyxj.study02.config.MyAuthenticationSuccessHandler;
import cn.cxyxj.study02.config.MyLogoutSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
//@EnableWebSecurity  如果你的项目是 SpringBoot 项目，该注解就没必要写
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("cxyxj")
                .password("123").roles("admin","user")
                .and()
                .withUser("security")
                .password("security").roles("user");

        auth.userDetailsService(userDetailsService());
    }

    /**
     * 配置自定义表单登录
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()  //开启配置
                .anyRequest() //其他请求
                .authenticated()//验证   表示其他请求需要登录才能访问
                .and()
                // 增加如下
                .formLogin()
                .loginPage("/login.html") //登录页面
                .loginProcessingUrl("/auth/login") //登录接口，此地址可以不真实存在
                .usernameParameter("account") //用户名字段
                .passwordParameter("pwd") //密码字段
                .defaultSuccessUrl("/hello")  //登录成功的回调
                .permitAll() // 上述 login.html 页面、/auth/login接口放行
                .and()
                .csrf().disable();  // 禁用 csrf 保护
    }

   // 前后端不分离的登录回调
/*    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()  //开启配置
                // /hello2、/hello4接口可以直接访问，不需要登录
                .antMatchers("/hello2","/hello4").permitAll()
                .anyRequest() //其他请求
                .authenticated()//验证   表示其他请求需要登录才能访问
                .and()
                // 增加如下
                .formLogin()
                .loginPage("/login.html") //登录页面
                .loginProcessingUrl("/auth/login") //登录接口，此地址可以不真实存在
                .usernameParameter("account") //用户名字段
                .passwordParameter("pwd") //密码字段
                .defaultSuccessUrl("/hello")  //登录成功的回调
                .successForwardUrl("/hello3")
                .failureUrl("/hello2")
                .failureForwardUrl("/hello4")
                .permitAll() // 上述 login.html 页面、/auth/login接口放行
                .and()
                .csrf().disable();  // 禁用 csrf 保护
    }*/

    // 前后端分离的登录回调
    /*@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()  //开启配置
                // /hello2、/hello4接口可以直接访问，不需要登
                .antMatchers("/hello2","/hello4").permitAll()
                .anyRequest() //其他请求
                .authenticated()//验证   表示其他请求需要登录才能访问
                .and()
                .formLogin()
                .loginPage("/login.html") //登录页面
                .loginProcessingUrl("/auth/login") //登录接口，此地址可以不真实存在
                .usernameParameter("account") //用户名字段
                .passwordParameter("pwd") //密码字段
                // 增加如下
                .successHandler(new MyAuthenticationSuccessHandler())
                .failureHandler(new MyAuthenticationFailureHandler())
                .permitAll() // 上述 login.html 页面、/auth/login接口放行
                .and()
                .csrf().disable()  // 禁用 csrf 保护
                .exceptionHandling().authenticationEntryPoint(new MyAuthenticationEntryPoint());
    }*/

    // 前后端不分离注销登录
    /*@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()  //开启配置
                // /hello2、/hello4接口可以直接访问，不需要登
                .antMatchers("/hello2","/hello4").permitAll()
                .anyRequest() //其他请求
                .authenticated()//验证   表示其他请求需要登录才能访问
                .and()
                .formLogin()
                .loginPage("/login.html") //登录页面
                .loginProcessingUrl("/auth/login") //登录接口，此地址可以不真实存在
                .usernameParameter("account") //用户名字段
                .passwordParameter("pwd") //密码字段
                .permitAll() // 上述 login.html 页面、/auth/login接口放行
                .and()
                .csrf().disable()  // 禁用 csrf 保护
                 // 增加如下
                .logout()  //开启注销登陆
                .logoutUrl("/auth/logout") //注销请求url
                .logoutSuccessUrl("/login.html") //注销成功后要跳转的页面
                .deleteCookies()  // 清除 cookie
                .clearAuthentication(true) //清除认证信息
                .invalidateHttpSession(true) //使session失效
                .permitAll()
                ;
    }*/

    // 前后端分离注销登录
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//
//        http.authorizeRequests()  //开启配置
//                // /hello2、/hello4接口可以直接访问，不需要登
//                .antMatchers("/hello2","/hello4").permitAll()
//                .anyRequest() //其他请求
//                .authenticated()//验证   表示其他请求需要登录才能访问
//                .and()
//                .formLogin()
//                .loginPage("/login.html") //登录页面
//                .loginProcessingUrl("/auth/login") //登录接口，此地址可以不真实存在
//                .usernameParameter("account") //用户名字段
//                .passwordParameter("pwd") //密码字段
//                .permitAll() // 上述 login.html 页面、/auth/login接口放行
//                .and()
//                .csrf().disable()  // 禁用 csrf 保护
//                // 增加如下
//                .logout()
//                .logoutUrl("/auth/logout") //注销请求url
//                .logoutSuccessHandler(new MyLogoutSuccessHandler())
//                .permitAll();
//    }

    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        return username -> new User("hhhhh", "12345",
                AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }


}
